package references

import (
	"hi-jvm/instructions/base"
	"hi-jvm/rtda"
	"hi-jvm/rtda/heap"
)

// Invoke a class (static) method
type INVOKE_STATIC struct{ base.Index16Instruction }

func (self *INVOKE_STATIC) Execute(frame *rtda.Frame) {
	resolvedMethod := readStaticMethod(frame, self)

	ret := checkStaticInited(frame, resolvedMethod)
	if !ret	{
		return
	}

	base.InvokeMethod(frame, resolvedMethod)
}

func checkStaticInited(frame *rtda.Frame, method *heap.Method) bool {
	class := method.Class
	if !class.InitClassIfNotInited(frame) {
		return false
	}
	return true
}

func readStaticMethod(frame *rtda.Frame, invoke *INVOKE_STATIC) *heap.Method {

	cp := frame.Method.Class.ConstantPool
	methodRef := cp.GetConstant(invoke.Index).(*heap.MethodRef)
	resolvedMethod := methodRef.ResolvedMethod()
	if !resolvedMethod.IsStatic() {
		panic("java.lang.IncompatibleClassChangeError")
	}

	return resolvedMethod
}

